Skip to content

Fix sleep session splitting across midnight boundary#15

Open
hoveeman wants to merge 5 commits into
saksham2001:mainfrom
hoveeman:fix/sleep-midnight-splitting
Open

Fix sleep session splitting across midnight boundary#15
hoveeman wants to merge 5 commits into
saksham2001:mainfrom
hoveeman:fix/sleep-midnight-splitting

Conversation

@hoveeman

Copy link
Copy Markdown
Contributor

Currently, sleep packets are grouped into database sessions using the packet's start date (via calendar.startOfDay). If a user falls asleep before midnight (e.g., 11:30 PM), the sleep blocks before midnight are stored in a session dated yesterday, while blocks after midnight are stored in today's session. Since the Today view only queries for today's session date, the pre-midnight portion is hidden, making it look like sleep was only calculated from 12:00 AM on.

This PR changes the grouping logic to use a noon-to-noon boundary, mapping sleep starting at or after 12:00 PM to the next day's waking morning. This unifies the entire night's sleep under a single session dated on the morning of waking.

An integration unit test has been added to verify the cross-midnight merging behavior.

Group sleep packets using a noon-to-noon boundary (12:00 PM to 12:00 PM) instead of start-of-day. This prevents a single night's sleep that starts before midnight from being split into two database sessions, ensuring the pre-midnight portion correctly shows up on the morning's waking day.
@hoveeman hoveeman requested a review from saksham2001 as a code owner June 23, 2026 15:49
@hoveeman hoveeman force-pushed the fix/sleep-midnight-splitting branch from 1a19404 to 1bb529c Compare June 25, 2026 13:42
…it deinit

testCrossMidnightSleepMerging crashed the CI test runner with SIGABRT (a
libmalloc double-free), which also got mis-attributed to the adjacent
testBlocksOnlyForDayRange. The crash log points at
EventPersistenceSubscriber.__deallocating_deinit ->
swift_task_deinitOnExecutorMainActorBackDeploy: the synthesized main-actor
deinit hops through a back-deploy shim that double-frees on iOS < 26.5, which
is the runtime the GitHub runner uses (it ran on iOS 18.6 here). Production is
unaffected because the app keeps a single subscriber alive for its lifetime;
only a unit test that creates and drops one triggers the dealloc path.

Adding an explicit (non-isolated) deinit avoids the buggy executor-hop codegen
and also cancels the outstanding event/flush tasks, which is correct hygiene.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant